package com.dd.census.service.impl;

import com.dd.census.entity.*;
import com.dd.census.mapper.*;
import com.dd.census.service.*;
import com.dd.census.tools.Utils;
import com.dd.census.tools.excel.test.DemoEntity;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.StringUtils;
import java.text.DecimalFormat;
import java.text.SimpleDateFormat;
import java.util.*;

/**
 * 业务层实现类
 * AttendanceServiceImpl
 * @author whn
 * @date 2021/02/20
 */
@Service
public class AttendanceServiceImpl implements AttendanceService {

    @Autowired
	AttendanceMapper attendanceMapper;

	@Autowired
	Staff1Mapper staff1Mapper;

	@Autowired
	ParameterMapper parameterMapper;

	@Autowired
	AttendanceDetailsMapper attendanceDetailsMapper;

	@Autowired
	DeviceMapper deviceMapper;

	@Autowired
	SysUserMapper userMapper;

    @Override
    public int  insert(Attendance attendance) {
    	//回款或者考勤默认先走此方法
		Calendar cal = Calendar.getInstance();
		int year = cal.get(Calendar.YEAR);
		int month = cal.get(Calendar.MONTH);
 		String monthStr = String.valueOf(month);
		if(month<10){
			monthStr = "0" + monthStr;
		}
		Staff1 staff1 = new Staff1();
		staff1.setAttendanceDate(year+"-"+monthStr+"-01") ; // 考勤月份
		//根据考勤月份所有对应月份下应该有考勤的员工
		List<Staff1>  MonthStaff1list = staff1Mapper.selectList(staff1);
		//搜索现有考勤以及回款数据是否已经生成过对应月份的数据
		Attendance nowattendance = new Attendance();
		nowattendance.setAdYearMonth(year+"-"+monthStr);
		List<Attendance> nowattendancelist = attendanceMapper.selectList(nowattendance);
		List<Attendance> selectListAll = new ArrayList<>();
		//size为0则没有生成要重新生成否则已经生成过对应数据
		if(nowattendancelist.size() == 0){
			for(Staff1 s: MonthStaff1list){
				nowattendance = new Attendance();
				String adstaffType = "0";
				nowattendance.setAdUserId(s.getId());
				nowattendance.setAdYearMonth(year+"-"+monthStr);
				nowattendance.setCreateUserId(attendance.getCreateUserId());
				nowattendance.setCreateTime(new Date());
				nowattendance.setUpdateTime(new Date());
				// 非合同 0 合同 1 蓝领2
				if(s.getCategory() == 1){
					if(s.getContract() !=null && 1 == s.getContract()){
						adstaffType = "1";
					}else if(s.getContract() !=null && 2 == s.getContract()){
						adstaffType = "0";
						// 如果员工单价不为空则应回款金额为单价数
						if(!StringUtils.isEmpty(s.getPrice())){
							nowattendance.setAdDuerec(Double.valueOf(s.getPrice()));
						}
						nowattendance.setAdSalary(Double.valueOf(s.getSalary()));
					}
				}else if(s.getCategory() == 2){
					adstaffType = "2";
					// 蓝领默认0
					nowattendance.setAdSalary(Double.valueOf(0));
					// 应回款金额
					// 三个月
					if(s.getMethod() == 2){
						// 入场月份
						String monthW = s.getWorktime().split("-")[1];
						// 第一个月
						if(month == Integer.parseInt(monthW)){
							nowattendance.setAdDuerec(Double.valueOf(s.getMonth01()));
						}else if(month == Integer.parseInt(monthW) +1){
							nowattendance.setAdDuerec(Double.valueOf(s.getMonth02()));
						}else if(month == Integer.parseInt(monthW) +2){
							nowattendance.setAdDuerec(Double.valueOf(s.getMonth03()));
						}else{
							continue;
						}
					}else{
						// 一次 当前月 > 入场时间  1月入场  3月份不生成
						if(s.getMethod() == 1){
							// 入场月份
							String monthW = s.getWorktime().split("-")[1];
							// 只有入场后一个月生成回款
							if(month != Integer.parseInt(monthW)){
								continue;
							}
						}
						nowattendance.setAdDuerec(Double.valueOf(s.getAmount()));
					}
				}
				nowattendance.setAdStaffType(adstaffType);
				selectListAll.add(nowattendance);
			}
		}else{
			// 当数据库里已经生成当月考勤了则查询有没有当月新增人员或删除的人员没有在数据库里
			boolean flag = true;
			for(Staff1 s: MonthStaff1list){
				flag = true;
				for(Attendance a: nowattendancelist){
					//if(s.getId() == a.getAdUserId())如果用这个做判断会发生误判 具体原因未知 两者相等用==也会判断为不相等
					//但是建立两个int变量做==比较则不会出现误判 所以此处需要新增变量判断
					int sta = s.getId();
					int attd = a.getAdUserId();
					if(sta == attd){
						flag = false;
						break;
					}
				}
				if(flag){
 					String adstaffType = "0";
					nowattendance = new Attendance();
					nowattendance.setAdUserId(s.getId());
					nowattendance.setAdYearMonth(year+"-"+monthStr);
					nowattendance.setCreateUserId(attendance.getCreateUserId());
					nowattendance.setCreateTime(new Date());
					// 非合同 0 合同 1 蓝领2
					if(s.getCategory() == 1){
						if(s.getContract() !=null && 1 == s.getContract()){
							adstaffType = "1";
						}else if(s.getContract() !=null && 2 == s.getContract()){
							adstaffType = "0";
							if(!StringUtils.isEmpty(s.getPrice())){
								nowattendance.setAdDuerec(Double.valueOf(s.getPrice()));
							}
							// 非合同
							nowattendance.setAdSalary(Double.valueOf(s.getSalary()));
						}
					}else if(s.getCategory() == 2){
						// 蓝领默认0
						nowattendance.setAdSalary(Double.valueOf(0));
						adstaffType = "2";
						// 应回款金额
						// 三个月
						if(s.getMethod() == 2){
							// 入场月份
							String monthW = s.getWorktime().split("-")[1];
							// 第一个月
							if(month == Integer.parseInt(monthW)){
								nowattendance.setAdDuerec(Double.valueOf(s.getMonth01()));
							}else if(month == Integer.parseInt(monthW) +1){
								nowattendance.setAdDuerec(Double.valueOf(s.getMonth02()));
							}else if(month == Integer.parseInt(monthW) +2){
								nowattendance.setAdDuerec(Double.valueOf(s.getMonth03()));
							}else{
								continue;
							}
						}else{
							// 一次 当前月 > 入场时间  1月入场  3月份不生成
							if(s.getMethod() == 1){
								// 入场月份
								String monthW = s.getWorktime().split("-")[1];
								// 只有入场后一个月生成回款
								if(month != Integer.parseInt(monthW)){
									continue;
								}
							}
							nowattendance.setAdDuerec(Double.valueOf(s.getAmount()));
						}
					}
					nowattendance.setAdStaffType(adstaffType);
					selectListAll.add(nowattendance);
				}
			}
			if(selectListAll.size() ==0) return 0;
		}
    	return attendanceMapper.insertNew(selectListAll);
    }

    @Override
	@Transactional
    public int update(Attendance attendance) {
		//获取该次回款候选人信息
		Staff1 staff1= staff1Mapper.selectByKey(attendance.getAdUserId().toString());
    	if(attendance.getAdReceivalFlag() || (staff1.getCategory() == 2 && attendance.getAdInvoice())){
			// 查询是否保存实际绩效提成
			AttendanceDetails attd = new AttendanceDetails();
			attd.setAttendanceID(attendance.getAdId().toString());
			attd.setTargetMonth(attendance.getAdYearMonth());
			//根据该人员对应回款月份以及考勤记录id获取该人员应有提成的身份角色
			List<AttendanceDetails> attds =attendanceDetailsMapper.selectList(attd);
			Parameter parameter = new Parameter();
			List<Parameter> parameters = parameterMapper.selectList(parameter);
			Map<String,Double> mapParameters = new HashMap<>();
			for(Parameter s: parameters){
				mapParameters.put(s.getCode(),Double.valueOf( s.getValue()));
			}
			List<AttendanceDetails> attendanceDetails = getAttendanceDetails(staff1,attendance,mapParameters,attendance.getAdYearMonth());
			if(attds.size() == 0){
				// 新增
				attendanceDetailsMapper.batchInsert(attendanceDetails);

			}else{
    			// 修改因可能发生身份角色更换情况保险起见删除后新增
				attendanceDetailsMapper.batchDelete(attds);
				attendanceDetailsMapper.batchInsert(attendanceDetails);
			}
		}else{
			AttendanceDetails attd = new AttendanceDetails();
			attd.setAttendanceID(attendance.getAdId().toString());
			List<AttendanceDetails> attds =attendanceDetailsMapper.selectList(attd);
			if(attds.size() > 0){
				// 删除绩效详情
				attendanceDetailsMapper.batchDelete(attds);
			}
		}
    	return attendanceMapper.update(attendance);
    }

	private  List<AttendanceDetails> getAttendanceDetails(Staff1 staff1, Attendance attendance,Map<String,Double> mapParameters ,String targetMonth){
		SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM");
		List<AttendanceDetails> attendanceDetailList = new ArrayList<>();
		AttendanceDetails attendanceDetail;
		//attendanceDetail2 如果该候选人有招聘者角色人员则用2来计算提成
		AttendanceDetails attendanceDetail2;
		//attendanceDetail2 如果该候选人有渠道介绍人角色人员则用3来计算提成
		AttendanceDetails attendanceDetail3;
		//attendanceDetail2 如果该候选人有运营者角色人员则用4来计算提成
		AttendanceDetails attendanceDetail4;
		Double wxyjzjcb=mapParameters.get("wxyjzjcb");
		Double zptcbl=mapParameters.get("zptcbl");
		Double swtcbl=mapParameters.get("swtcbl");
		Double yytcbl=mapParameters.get("yytcbl");
		Double fp = 0.0;
		//提成=（汇款）实际汇款金额 - 当月薪资 -五险一金成本 - （实际*发票比例）  * 提成比例
		if(null != staff1.getInvoice()){
			if( 1 == staff1.getInvoice()){
				fp = 1.2 * 0.01;
			}else if(2 == staff1.getInvoice() || 3 == staff1.getInvoice()){
				fp = 3 * 1.2 * 0.01;
			}else if(4 == staff1.getInvoice() ){
				fp = 6 * 1.2 * 0.01;
			}else{
				fp = 0.0;
			}
		}
		attendanceDetail = new AttendanceDetails();
		attendanceDetail.setName(attendance.getsName());
		attendanceDetail.setWeekDate(staff1.getWorktime());
		attendanceDetail.setTargetMonth(targetMonth);
		// 当月回款金额
		attendanceDetail.setMonthRemittance(attendance.getAdReceival());
		// 当月成本 = 五险一金 + 当月薪资 + 发票_ 补助 + 商务 +设备费用
		double business = !StringUtils.isEmpty(staff1.getBusiness())? Double.valueOf(staff1.getBusiness()):0.0;
		double subsidy = !StringUtils.isEmpty(staff1.getSubsidy())? Double.valueOf(staff1.getSubsidy()):0.0;
		// 查询该候选人是否有设备费用 如果用计算入成本
		double devicepay = 0.0;
		List<Device> dlist = deviceMapper.selectAlldecive();
		for(Device d : dlist){
			int duserid = !StringUtils.isEmpty(d.getNowuserid())? Integer.valueOf(d.getNowuserid()):0;
			int staffid = staff1.getId();
			if(duserid == staffid){
				devicepay += Double.valueOf(d.getPrice());
			}
		}
		attendanceDetail.setMonthCost(Utils.doubleRetain(wxyjzjcb + attendance.getAdSalary() + attendanceDetail.getMonthRemittance()*fp) + business + subsidy + devicepay);
		attendanceDetail.setMonthProfit( Utils.doubleRetain(attendanceDetail.getMonthRemittance()-attendanceDetail.getMonthCost()));
		attendanceDetail.setStaffId(staff1.getId().toString());
		attendanceDetail.setAttendanceID(attendance.getAdId().toString());
		//蓝领员工比较特殊因为是根据是否回款对账做提成标准所以提成日期按照对账日期走
		if(staff1.getCategory() == 2){
			attendanceDetail.setAttendanceMonth(sdf.format(attendance.getAdEstimate()));
		}else{
			attendanceDetail.setAttendanceMonth(sdf.format(attendance.getAdCollection()));
		}
		if(!StringUtils.isEmpty(staff1.getLeaderId()) ){
			attendanceDetail2 = (AttendanceDetails)attendanceDetail.clone();;
			Double tc2 = attendanceDetail2.getMonthProfit() * zptcbl;
			attendanceDetail2.setCommission(Utils.doubleRetain(tc2));
			attendanceDetail2.setRoleStr("招聘者");
			attendanceDetail2.setUserId(staff1.getLeaderId() );
			attendanceDetailList.add(attendanceDetail2);
		}
		if(!StringUtils.isEmpty(staff1.getDirectorId()) ){
		    // 因为运营者不拿渠道推荐奖励所以要排除运营者身份
			SysUser nowuser = userMapper.getSysUserById(Integer.parseInt(staff1.getDirectorId()));
			if(nowuser.getRoleId()!=9){
				attendanceDetail3 = (AttendanceDetails)attendanceDetail.clone();;
				Double tc3  = attendanceDetail3.getMonthProfit() * swtcbl;
				attendanceDetail3.setCommission(Utils.doubleRetain(tc3));
				attendanceDetail3.setRoleStr("渠道介绍人");
				attendanceDetail3.setUserId(staff1.getDirectorId());
				attendanceDetailList.add(attendanceDetail3);
			}
		}
		if(!StringUtils.isEmpty(staff1.getOperateId()) ){
			attendanceDetail4 = (AttendanceDetails)attendanceDetail.clone();;
			Double tc4  = attendanceDetail4.getMonthProfit() * yytcbl;
			attendanceDetail4.setCommission(Utils.doubleRetain(tc4));
			attendanceDetail4.setRoleStr("运营者");
			attendanceDetail4.setUserId(staff1.getOperateId());
			attendanceDetailList.add(attendanceDetail4);
		}
		return attendanceDetailList;
	}

    @Override
    public int delete(Attendance attendance) {
    	return attendanceMapper.delete(attendance);
    }

	@Override
	public Attendance selectByKey(String key) {
		return attendanceMapper.selectByKey(key);
	}

	@Override
	public List<Attendance> selectList(Attendance attendance) {
		return attendanceMapper.selectList(attendance);
	}

	@Override
	public Map<String, Object> selectPage(Attendance attendance) {
		Map<String, Object> map = new HashMap<String, Object>();
		int total = this.total(attendance);
		map.put("pageCount", Math.ceil((double) total / attendance.getPageSize()));// 总页数
		map.put("total", total);// 总条数
		map.put("index", attendance.getPageIndex());// 当前页
		if (total > 0) {
			attendance.setPageIndex(attendance.getPageSize() * (attendance.getPageIndex() - 1));
			map.put("items", attendanceMapper.selectPage(attendance));
		}
		return map;
	}

	@Override
	public int total(Attendance attendance) {
		return attendanceMapper.total(attendance);
	}

	@Override
	public int excelImport(List<DemoEntity> list,Attendance attendance) throws Exception {
    	int adDueatt = 0;
    	double attendanceDay = 0; // 实际出勤日
		DecimalFormat df=new DecimalFormat("0.00");//设置保留位数
		Staff1 staff1 = staff1Mapper.selectByKey(String.valueOf(attendance.getAdUserId()));
		SimpleDateFormat sdf =   new SimpleDateFormat( "yyyy-MM-dd" );
		for(DemoEntity s: list){
			if(null ==s.getBirthday()){
				break;
			}
			if(s.getIsWork().equals("是")){
				adDueatt  = adDueatt +1;
				attendanceDay =attendanceDay+s.getValue();
			}
		}
		//实际出勤/当月应出勤*薪资=当月薪资
		String adSalary = df.format((attendanceDay/adDueatt)*Double.valueOf(staff1.getSalary()));
		//实际出勤/当月应出勤*单价=当月薪资
		String adDuerec = df.format((attendanceDay/adDueatt)*Double.valueOf(staff1.getPrice()));
		// 预计该月回款日（首次汇款-人入职）+当前月
		String[] date1 = staff1.getPaydate().split("-"); //首次汇款-
		Integer dateStart = Integer.parseInt(date1[0]) * 12 + Integer.parseInt(date1[1]);
		String[] date2 = staff1.getWorktime().split("-"); //人入职
		Integer daterz = Integer.parseInt(date2[0]) * 12 + Integer.parseInt(date2[1]);
		Integer date = dateStart-daterz;
		Calendar c = Calendar.getInstance();
		c.add(Calendar.MONTH, date);
		String adEstimate = Utils.getDateLastDay(c.get(Calendar.YEAR),c.get(Calendar.MONTH));
		Attendance attendance1 = new Attendance();
		attendance1.setAdDueatt(String.valueOf(df.format(adDueatt)) );
		attendance1.setAdAttend(String.valueOf(df.format(attendanceDay)));
		attendance1.setAdId(attendance.getAdId());
		attendance1.setAdSalary(Double.valueOf( adSalary));
		attendance1.setAdDuerec(Double.valueOf(adDuerec));
		attendance1.setAdEstimate(sdf.parse(adEstimate));
		return attendanceMapper.update(attendance1);
	}
}